package com.gateio.flutter.lib_furnace.container

import android.app.Activity
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.OnLifecycleEvent
import com.gateio.flutter.lib_furnace.GTFlutterInitializer
import io.flutter.embedding.android.ExclusiveAppComponent
import io.flutter.embedding.android.FlutterView
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.platform.PlatformPlugin

/**
 * Author: Shper
 * Created: 2023/7/12
 */
class GTFlutterViewEngine(val engine: FlutterEngine) : LifecycleObserver, ExclusiveAppComponent<Activity> {

    private var flutterView: FlutterView? = null
    private var activity: AppCompatActivity? = null
    private var platformPlugin: PlatformPlugin? = null

    private fun hookActivityAndView(delegate: PlatformPlugin.PlatformPluginDelegate,
                                    onComplete: ((engine: FlutterEngine) -> Unit)) {
        activity?.let { activity ->
            flutterView?.let { flutterView ->
                platformPlugin = PlatformPlugin(activity, engine.platformChannel, delegate)

                engine.activityControlSurface.attachToActivity(this, activity.lifecycle)
                // flutterView 和 引擎 进行绑定
                flutterView.attachToFlutterEngine(engine)
                // 通知引擎已经加载，主工程进行 原生功能初始化
                GTFlutterInitializer.getHostDelegate()?.configureFlutterEngine(activity, false, engine)
                onComplete.invoke(engine)
                // 增加生命周期监控
                activity.lifecycle.addObserver(this)
            }
        }
    }

    private fun unhookActivityAndView() {
        // 通知 flutter pop，让 WillPopScope 接收
        //engine.navigationChannel.popRoute()
        // 删除生命周期监控
        activity?.lifecycle?.removeObserver(this)
        // 解除绑定
        engine.activityControlSurface.detachFromActivity()

        platformPlugin?.destroy()
        platformPlugin = null
        // 通知 flutter 生命周期走 Detached
        engine.lifecycleChannel.appIsDetached()
        // 解除 flutterView 和 引擎绑定
        flutterView?.detachFromFlutterEngine()
    }

    fun attachFlutterView(activity: Activity,
                          flutterView: FlutterView,
                          delegate: PlatformPlugin.PlatformPluginDelegate,
                          onComplete: ((engine: FlutterEngine) -> Unit)) {
        this.flutterView = flutterView

        if (activity is AppCompatActivity) {
            this.activity = activity
            hookActivityAndView(delegate, onComplete)
        }
    }

    fun detachFlutterView() {
        unhookActivityAndView()

        activity = null
        flutterView = null
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    private fun resumeActivity() {
        if (activity != null) {
            engine.lifecycleChannel.appIsResumed()
        }

        platformPlugin?.updateSystemUiOverlays()
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    private fun pauseActivity() {
        if (activity != null) {
            engine.lifecycleChannel.appIsInactive()
        }
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    private fun stopActivity() {
        if (activity != null) {
            engine.lifecycleChannel.appIsPaused()
        }
    }

    fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
        if (activity != null && flutterView != null) {
            engine.activityControlSurface.onRequestPermissionsResult(requestCode, permissions, grantResults)
        }
    }

    fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        if (activity != null && flutterView != null) {
            engine.activityControlSurface.onActivityResult(requestCode, resultCode, data)
        }
    }

    fun onUserLeaveHint() {
        if (activity != null && flutterView != null) {
            engine.activityControlSurface.onUserLeaveHint()
        }
    }

    override fun detachFromFlutterEngine() {
        // Do nothing here
    }

    override fun getAppComponent(): Activity {
        return activity!!
    }

}